import time
import faker


class CreateCreditCode(object):

    # 统一社会信用代码中不使用I,O,Z,S,V
    SOCIAL_CREDIT_CHECK_CODE_DICT = {
        '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
        'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17, 'J': 18,
        'K': 19, 'L': 20, 'M': 21, 'N': 22, 'P': 23, 'Q': 24,
        'R': 25, 'T': 26, 'U': 27, 'W': 28, 'X': 29, 'Y': 30}
    # GB11714-1997全国组织机构代码编制规则中代码字符集
    ORGANIZATION_CHECK_CODE_DICT = {
        '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
        'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17, 'I': 18,
        'J': 19, 'K': 20, 'L': 21, 'M': 22, 'N': 23, 'O': 24, 'P': 25, 'Q': 26,
        'R': 27, 'S': 28, 'T': 29, 'U': 30, 'V': 31, 'W': 32, 'X': 33, 'Y': 34, 'Z': 35}
    @classmethod
    def createc9(cls, test_code):
        # 第i位置上的加权因子
        weighting_factor = [3, 7, 9, 10, 5, 8, 4, 2]
        # 第9~17位为主体标识码(组织机构代码)
        organization_code = test_code[8:17]
        # 本体代码
        ontology_code = organization_code[0:8]
        # 生成校验码
        tmp_check_code = cls.gen_check_code(
            weighting_factor, ontology_code, 11, cls.ORGANIZATION_CHECK_CODE_DICT)
        return test_code[:16] + tmp_check_code
    @classmethod
    def gen_check_code(cls, weighting_factor, ontology_code, modulus, check_code_dict):
        total = 0
        for i in range(len(ontology_code)):
            if ontology_code[i].isdigit():
                total += int(ontology_code[i]) * weighting_factor[i]
            else:
                total += check_code_dict[ontology_code[i]
                                         ] * weighting_factor[i]
        c9 = modulus - total % modulus
        c9 = 0 if c9 == 31 else c9
        c9 = list(check_code_dict.keys())[
            list(check_code_dict.values()).index(c9)]
        return c9
    @classmethod
    def get_social_creditcode(cls, test_code):
        test_code = cls.createc9(test_code[:16])
        # 第i位置上的加权因子
        weighting_factor = [1, 3, 9, 27, 19, 26, 16,
                            17, 20, 29, 25, 13, 8, 24, 10, 30, 28]
        # 本体代码
        ontology_code = test_code[0:17]
        # 计算校验码
        tmp_check_code = cls.gen_check_code(
            weighting_factor, ontology_code, 31, cls.SOCIAL_CREDIT_CHECK_CODE_DICT)
        return test_code[:17] + tmp_check_code
    @classmethod
    def unique_social_creditcode(cls, code):
        uid = time.strftime("%Y%m%d%H%M%S", time.localtime())
        newcode = str(code + int(uid))
        social_creditcode = CreateCreditCode.get_social_creditcode(newcode)
        return social_creditcode
if __name__ == '__main__':
    credit_code = CreateCreditCode.unique_social_creditcode(5153280000000001)
    print('统一社会信用代码：',credit_code)
    fake = faker.Faker('zh_CN')
    id_card_num = fake.ssn(min_age=18, max_age=100)
    print('身份证：',id_card_num)